/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tt.view;

import tt.VorlesungenService.EntityService;
import tt.model.Lecturedate;
import tt.model.Lecture;
import tt.model.Courseschedule;
import java.util.Collection;
import tt.model.Courseofstudy;

import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;


import java.util.Date;
import tt.Exception.EntityServiceException;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import java.io.Serializable;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletRequest;
import tt.model.*;
import tt.VorlesungenService.UniqueIDGenerator;

/**
 *
 * @author andi
 */
@ManagedBean
@SessionScoped
public class timetableBean implements Serializable {

    @EJB
    private EntityService service;
    private String coursescheduleid, courseid;
    private Courseschedule mySchedule;
    private boolean zeigeEinfuehrung = false;
    private String captchaIDURL, captchaIDCookie;
    int semester;

    public void logging(String text) {
        Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, text);
    }//end method

    public String getCaptchaIDCookie() {
        return captchaIDCookie;
    }

    public void generateCaptchaIDCookie() {
        UniqueIDGenerator idgen = new UniqueIDGenerator();
        captchaIDCookie = idgen.getNewID();
    }//end try

    public void generateCaptchaIDURL() {
        UniqueIDGenerator idgen = new UniqueIDGenerator();
        captchaIDURL = idgen.getNewID();
    }//end try

    public void setCaptchaIDCookie(String captchaIDCookie) {
        this.captchaIDCookie = captchaIDCookie;
    }

    public String getCaptchaIDURL() {
        return captchaIDURL;
    }

    public void setCaptchaIDURL(String captchaIDURL) {
        this.captchaIDURL = captchaIDURL;
    }

    public String getCourseid() {
        return courseid;
    }

    public void setCourseid(String courseid) {
        this.courseid = courseid;
    }

    public int getSemester() {
        return semester;
    }

    public void setSemester(int semester) {
        this.semester = semester;
    }

    public boolean isZeigeEinfuehrung() {
        return zeigeEinfuehrung;
    }

    public void setZeigeEinfuehrung(boolean zeigeEinfuehrung) {
        this.zeigeEinfuehrung = zeigeEinfuehrung;
    }

    public String getCoursescheduleid() {
        return coursescheduleid;
    }

    public void setCoursescheduleid(String coursescheduleid) {
        Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, "setID: " + coursescheduleid);
        this.coursescheduleid = coursescheduleid;
        setLectureDateCollectionByCourseScheduleID();
        Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, "danach:" + this.coursescheduleid);
    }

    public Collection<Lecturedate> getLectureDateCollectionByCourseSchedule() {
        setLectureDateCollectionByCourseScheduleID();
        return mySchedule.getLecturedateCollection();

    }//end method

    private void setLectureDateCollectionByCourseScheduleID() {
        try {
            mySchedule = service.getCourseScheduleByIDCourseSchedule(coursescheduleid);
            // Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, new Date().toString() + "Size new mySchedule: " + mySchedule.getLecturedateCollection().size());
        } catch (EntityServiceException e) {
            Logger.getLogger(timetableBean.class.getName()).log(Level.WARNING, "Exception creating new LecturedateCollection Object");
        }//endtry
    }//end method

    public String getSessionidFromBean() {
        FacesContext fCtx = FacesContext.getCurrentInstance();
        HttpSession session = (HttpSession) fCtx.getExternalContext().getSession(false);
        return session.getId();
    }//endmethod

    public Collection<Lecture> getNotAddedLectureCollection() {
        try {
            //Alle Lectures
            Collection<Lecture> allLectures = service.getLectureCollection();
            //Alle Lecturedates im aktuellen Schedule
            Collection<Lecturedate> myDates = getLectureDateCollectionByCourseSchedule();
            //Liste ist Kopie von allLecture - wird später befüllt.
            LinkedList<Lecture> newLectures = new LinkedList();

            //Hashmap inthält ID der Lecture als Key und die Anzahl der zugehörigen Lecture dates als Value
            HashMap hashLecture = new HashMap();
            Lecture tempLecture;

            //Schleife befüllt hilfsarrays
            for (Iterator<Lecture> it = allLectures.iterator(); it.hasNext();) {
                tempLecture = it.next();
                //hashmap wird befüllt
                hashLecture.put(tempLecture.getIdlecture().toString(), tempLecture.getLecturedateCollection().size());
                //Füge copy der aktuellen Lecture der neuen Liste hinzu
                newLectures.add(tempLecture.getCopy());
            }//end for

            Lecturedate tempLecturedate;

            //Schleife durchläuft alle Lecturedates und erniedrigt den Lecturedate zähler
            //ist dieser 0 ist die Vorlesung komplett im Plan enthalten und kann somit gelöscht werden
            for (Iterator<Lecturedate> it = myDates.iterator(); it.hasNext();) {
                tempLecturedate = it.next();
                String idLecture = tempLecturedate.getLecture().getIdlecture().toString();
                //update hash, erniedrige den Zähler um 1
                hashLecture.put(idLecture, Integer.parseInt(hashLecture.get(idLecture).toString()) - 1);
                //wenn der zähler auf 0 ist, sind alle Termine der Vorlesung enthalten - obj wird gelöscht
                if (Integer.parseInt(hashLecture.get(idLecture).toString()) == 0) {
                    newLectures.remove(tempLecturedate.getLecture());
                }
            }//end for


            return newLectures;
        } catch (EntityServiceException Ex) {
            return null;
        }//endtry
    }//end method

    public int getCountNotAddedLectureCollection(Courseofstudy course) {
        try {

            Collection myLectures = getNotAddedLectureCollection();
            Lecture myLecture;
            int counter = 0;
            for (Iterator<Lecture> it = myLectures.iterator(); it.hasNext();) {
                myLecture = it.next();

                //filtert nur die Lectures des Studiengangs raus, die mit übergeben wurden
                if (myLecture.getSemester().getCourseofstudy().getCoursename().compareTo(course.getCoursename()) == 0) {
                    counter++;
                }//endif

            }

            return counter;
        } catch (Exception Ex) {
            return 0;
        }//endtry
    }//end method

    private String getCookieParameter(String parametername) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        Map cookieMap = facesContext.getExternalContext().getRequestCookieMap();
        Cookie cookie = (Cookie) cookieMap.get(parametername);
        if (cookie != null && cookie.getValue().length() > 0) {
            String content = cookie.getValue();
            return content;
        } else {
            return null;
        }
        //endif

    }//end method

    private String getURLParameter(String parametername) {
        String value = null;
        try {
            HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
            value = request.getParameter(parametername).toString();
        } catch (Exception Ex) {
        }//end try
        return value;

    }//end method

    public void removeLectureDateFromCourseschedule(int iddate) {
        try {
            service.removeLectureDateFromCourseschedule(mySchedule, iddate);
            Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, "Lecturedate mit der ID " + iddate + " jetzt nicht mehr verknüpft");

        } catch (EntityServiceException e) {
            Logger.getLogger(timetableBean.class.getName()).log(Level.WARNING, e.toString());
        }//endtry
    }//endmethod

    public void addLectureToCourseschedule(int idLecture) {
        try {
            service.addLectureToCourseschedule(mySchedule, idLecture);
        } catch (EntityServiceException e) {
            Logger.getLogger(timetableBean.class.getName()).log(Level.WARNING, e.toString());
        }//endtry
    }//endmethod

    public void createCookie(String name, String value, int age) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        // Save the userid and password in a cookie
        Cookie myCookie = new Cookie(name, value);
        myCookie.setMaxAge(age); //= ein halbes Jahr
        myCookie.setPath("/Vorlesungsplan/");
        ((HttpServletResponse) facesContext.getExternalContext().getResponse()).addCookie(myCookie);
    }//endmethod

    public void removeCookie(String name) {
        createCookie(name, "", 0);
    }//end method

    public void createCookieFromBeanValue() {
        createCookie("schedule", this.coursescheduleid, 60 * 60 * 24 * 180);
    }//end method

    public String checkCourseScheduleIdFromCookie() {

        try {
            String content = getCookieParameter("schedule");

            //Prüfe ob Vorlesungsplan zur id überhaupt existiert, falls nicht, wird null returned
            if (scheduleExists(content) == false) {
                Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, "Cookie schedule-Parameter " + content + "nicht gültig!");
                return null;
            }
            Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, "Cookie schedule-Parameter gültig: " + content);
            setCoursescheduleid(content);

            return content;
        } catch (Exception Ex) {
            return null;
        }//end try


    }//endmethod

    public String checkCourseScheduleIdByURLParameter() {

        String id = getURLParameter("schedule");
        //Wenn eien ID zurückgegeben wurde...
        if (id != null) {
            //...prüfe ob der Vorlesungsplan zur ID überhaupt existiert
            if (scheduleExists(id) == false) {
                Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, "URL schedule-Parameter " + id + "nicht gültig!");
                return null;
            }//endif
            //Alles OK, ID wird in VAriable gschrieben, wenn sie nicht schon gesetzt ist 
            Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, "URL schedule-Parameter gültig: " + id);
            if (coursescheduleid != null) {
                if (id.compareTo(coursescheduleid) != 0) {
                    //CoursescheduleID wird gesetzt, wenn sie sich von der URL übergebenen unterscheidet
                    setCoursescheduleid(id);
                }//endif
            } else {
                //CoursescheduleID wird gesetzt, wenn sie noch nicht existiert
                setCoursescheduleid(id);
            }//endif
            return id;
        } else {
            Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, "Kein schedule-Parameter in der URL vorhanden!");
            return null;
        }//endif       
    }//end method

    public boolean checkCourseScheduleIdFromBean() {

        if (scheduleExists(coursescheduleid) == true) {
            setCoursescheduleid(coursescheduleid);
            Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, "Interner schedule-Parameter " + coursescheduleid + " gültig!");
            return true;
        } else {
            Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, "Interner schedule-Parameter " + coursescheduleid + " nicht gültig!");
            return false;
        }//end if


    }//end method

    public Lecture checkAddParameterFromURL() {
        try {
            String addLecture = getURLParameter("add");
            Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, "addParameter: " + addLecture);
            if (addLecture != null && checkSessionID() == true) {
                int addLectureInt = Integer.parseInt(addLecture);
                addLectureToCourseschedule(addLectureInt);
                return service.getLectureByIDLecture(addLectureInt);
            } else {
                Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, "Ungültiger oder kein Add Parameter in URL");
                return null;
            }//endif

        } catch (Exception Ex) {
            Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, "ungültiger Add Prameter in URL");
            return null;
        }//end try


    }//end method

    public boolean checkCreateParameterFromURL() {
        boolean rueck = false;
        try {
            String captchaIDURL = getURLParameter("create");
            Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, "create: " + captchaIDURL);
            if (captchaIDURL != null || this.captchaIDURL != null) { //&& checkSessionID() == true

                //Prüfe ob der Timestamp in der Bean mit der in der URL übereinstimmt
                if (this.getCaptchaIDURL().compareTo(captchaIDURL) == 0) {
                    Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, "Create Parameter gültig!");
                    //neuer Timestamp wird auf null gesetzt, damit alte URL ungültig ist
                    setCaptchaIDURL(null);
                    rueck = true;
                }

            } else {
                Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, "Kein create Parameter in URL");
            }//endif

        } catch (Exception Ex) {
            Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, "ungültiger Create Prameter in URL");
        }//end try
        return rueck;

    }//end method

    public void checkDeleteParameterFromURL() {
        try {
            String delLectureDate = getURLParameter("del");

            //wenn ein Delete Parameter und ein gültiger session Parameter übergeben wurde...
            if (delLectureDate != null && checkSessionID() == true) {
                int delLectureDateInt = Integer.parseInt(delLectureDate);
                removeLectureDateFromCourseschedule(delLectureDateInt);
            } else {
                Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, "Kein Delete Parameter");
            }//endif

        } catch (Exception Ex) {
            Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, "ungültiger delete Prameter");
        }//end try


    }//end method

    public boolean checkResetParameterFromURL() {
        try {
            String reset = getURLParameter("res");

            //wenn ein reset Parameter wurde...return true
            if (reset != null) {
                return true;
            } else {
                Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, "Kein reset Parameter");
                return false;
            }//endif

        } catch (Exception Ex) {
            Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, "ungültiger reset Prameter");
            return false;
        }//end try


    }//end method

    public boolean checkSessionID() {
        //Liefert true zurück, wenn die SessionID übereinstimmt 
        String sessionIDURL = getURLParameter("sess");
        Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, "SessionID URL: " + sessionIDURL);
        Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, "SessionID Bean" + getSessionidFromBean());
        if (sessionIDURL == null) {
            return false;
        } else if (sessionIDURL.compareTo(getSessionidFromBean()) == 0) {
            return true;
        } else {
            Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, "Session ID nicht mehr gültig");
            return false;
        }//endif
    }//end method

    public boolean validateParameter() {
        boolean validationstatus = true;


        //Checke ob in der URL ein schedule Parameter übergeben wurde und dieser gültig ist
        if (checkCourseScheduleIdByURLParameter() != null) {
            //URL gültig, ID wurde in Bean geschrieben 
            // Cookie wird ersellt
            createCookie("schedule", this.coursescheduleid, 60 * 60 * 24 * 180);
        } else {
            //Es wurde keine ID in der URL übergeben
            //checke ob schon eine ID im Bean hinterlegt -->
            //bei weiteren Seitenaufrufen i.d.R. der Fall-->
            if (checkCourseScheduleIdFromBean() == true) {
                //Bean Value validiert - Alles normal!-->
                //Wird geprüft, ob Cookie schon mit dem richtigen Wert existiert
                if (getCookieParameter("schedule") != null) {
                    if (getCookieParameter("schedule").compareTo(coursescheduleid) != 0) {
                        //Cookie Parameter ist nicht mehr Aktuell --> wird überschrieben
                        createCookie("schedule", this.coursescheduleid, 60 * 60 * 24 * 180);
                    }//endif
                } else {
                    //es existiert noch kein Cookie --> wird ertellt
                    createCookie("schedule", this.coursescheduleid, 60 * 60 * 24 * 180);
                }//endif
            } else {
                //keine gültige interne ID -->
                //Checke ob ID im Cookie vorhanden und enthaltene ID gültig-->
                if (checkCourseScheduleIdFromCookie() != null) {
                    //Cookie gültig, ID wurde in Bean geschrieben-->
                } else {
                    //Cookie ungültig oder nicht vorhanden -->
                    //Cookie wird gelöscht 
                    removeCookie("schedule");
                    // Weiterleitung zur Welcomeseite aktiviert
                    validationstatus = false;
                    redirect("welcome.xhtml");
                }//endif
            }//endif
        }//endif


        checkDeleteParameterFromURL();
        //checkAddParameterFromURL();


        return validationstatus;
    }//end method

    public void redirect(String site) {
        try {
            Logger.getLogger(timetableBean.class.getName()).log(Level.INFO, "Redirect auf " + site);
            FacesContext.getCurrentInstance().getExternalContext().redirect(site);
        } catch (Exception ex) {
        }//endtry
    }//end method

    public boolean scheduleExists(String idCourse) {
        return service.scheduleExists(idCourse);

    }//end method

    public Collection<Lecture> getLectureCollectionbyCourseSchedule() {   // Returntype: Collection<Lecture>
        setLectureDateCollectionByCourseScheduleID();
        return service.getLectureCollectionbyCourseSchedule(mySchedule);
    }//end mehtod

    public Collection<Courseofstudy> getCourseOfStudyCollection() {
        try {
            return service.getCourseOfStudyCollection();
        } catch (EntityServiceException Ex) {
            return null;
        }
    }

    public boolean deleteCourseschedule() {

        if (checkSessionID() == true) {
            try {
                boolean status = service.deleteCourseschedule(mySchedule);
                if (status == true) {
                    //redirect("welcome.xhtml");
                    return true;
                } else {
                    return false;
                }//end if

            } catch (Exception Ex) {
                return false;
            }//end try
        } else {
            return false;
        }
    }//end method

    public boolean checkCreateCourseschedulePramaterFromCookie(String value) {


        if (value.isEmpty()) {
            return false;
        }

        String activateButton = getCookieParameter("activateButton");
        if (activateButton != null) {
            if (activateButton.startsWith(value) == true) {
                return true;
            } else {
                return false;
            }
        } else {

            return false;
        }//end if

    }//end method

    public void createCourseSchedule() {
        try {
            coursescheduleid = service.createCourseSchedule(semester);
            //return coursescheduleid;
        } catch (Exception ex) {
            //return ex.toString();
        }//endtry

    }//end method

    public Collection<Lecture> getLectureCollectionBySemester() {
        Semester mySemester = null;
        try {
            mySemester = service.getSemesterByIDSemester(semester);
            return mySemester.getLectureCollection();

        } catch (EntityServiceException e) {
            return null;
        }//end try
    }//end method

    public Collection<Semester> getSemesterCollectionbyCourseofstudy() {
        try {
            return (service.getCourseOfStudyByIdCourse(courseid)).getSemesterCollection();
        } catch (EntityServiceException Ex) {
            return null;
        }//endtry
    }//end method

    public String getCurrentDay() {
        Date today = new Date();
        String day = today.toString().substring(0, 3);

        if (day.compareTo("Mon") == 0) {
            day = "Montag";
        } else if (day.compareTo("Tue") == 0) {
            day = "Dienstag";
        } else if (day.compareTo("Wed") == 0) {
            day = "Mittwoch";
        } else if (day.compareTo("Thu") == 0) {
            day = "Donnerstag";
        } else if (day.compareTo("Fri") == 0) {
            day = "Freitag";
        } else if (day.compareTo("Sat") == 0) {
            day = "Samstag";
        }

        return day;

    }//end method

    public static int getRandomForURL() {
        //Zufallszahl in URL verhindert Chaching --> hatten da extreme Probleme
        int low = 1000;
        int high = 99999;
        return (int) (Math.random() * (high - low) + low);
    }
}//end class
